import React, { Component, Suspense } from 'react';
import { connect } from 'dva';
import GridContent from '@/components/PageHeaderWrapper/GridContent';
import { FormattedMessage } from 'umi-plugin-react/locale';
import PageHeaderWrapper from '@/components/PageHeaderWrapper';
import PageLoading from '@/components/PageLoading';
import { Card, Button, Icon, Modal, message, Form, Input, Checkbox, Col, Row,Tag,Spin,Progress  } from 'antd';
import { Pie,TimelineChart,ChartCard, yuan, Field  } from '@/components/Charts';
import Trend from '@/components/Trend';
import numeral from 'numeral';
import echarts from 'echarts/lib/echarts';
import 'echarts/lib/chart/bar';
import 'echarts/lib/chart/line';
import 'echarts/lib/component/tooltip';
import 'echarts/lib/component/title';
import 'echarts/lib/component/legend';
import 'echarts/lib/component/toolbox';
import 'echarts/lib/component/markPoint';
import 'echarts/lib/component/markLine';
import styles from './index.less';
import img1 from '../../../assets/dialog/1.png';
import img2 from '../../../assets/dialog/2.png';
import img3 from '../../../assets/dialog/3.png';
import img4 from '../../../assets/dialog/4.png';

const SlotModal = React.lazy(() => import('./SlotModal'));
const FlowPage = React.lazy(() => import('./flow'));

const formItemLayout = {
  labelCol: { span: 1 },
  wrapperCol: { span: 20 },
};
let myChart;
@connect(({ DialogAdd, loading }) => ({
  DialogAdd,
  loading: loading.effects['dialogAdd/fetchSlot'],
}))
class DialogAdd extends Component {
  state = {
    visible: false, // 词槽弹窗是否显示
    limit:10, // 词槽每页加载数量
    page:1, // 词槽页数
    slotLoading:true, // 词槽加载loading
    slotTotal:0, // 词槽列表总数
    slotData:[], // 词槽列表
    keys:'', // 词槽搜索关键词
    slotList:[], // 添加的词槽列表
    dialogId:'',// 多轮对话id
    name:'', // 多轮对话name
    slotDetailVisible:false,
    stageTitle:[],
    dialogData:{},
    training:false,
    chartsIsShow:false,
    percent:0,
    intervalId:0,
    dialogObj:null,
    data:null,
    status:null
  };

  componentDidMount() {
    if(this.props.location.state.id){
      this.setState({
        dialogId: this.props.location.state.id,
        name: this.props.location.state.name
      },()=>{
        this.initDialog(this.props.location.state.id)
      })
    }

  }

  fetchSlot=()=>{
    const { dispatch } = this.props;
    const {limit,page,keys} = this.state;
    dispatch({
      type: 'dialogAdd/fetchSlot',
      payload: {
        limit,page,keys
      },
      callback:(res)=>{
        this.setState({
          slotTotal: res.total,
          slotData: res.list,
          slotLoading: false
        })
      }
    });
  };

  addSlotToDialogByAdd=(slotId,add)=>{
    const { dispatch } = this.props;
    const {dialogId} = this.state;
    dispatch({
      type: 'dialogAdd/addSlotToDialog',
      payload: {
        dialogId,
        isAdd:add!== undefined?add:true,
        slotId
      },
      callback:(res)=>{
       if(!res.code){
         message.info('执行成功');
         this.handleCancel();
         this.fetchDialogSlotByDialogId(dialogId)
       }
      }
    });
  };

  querySlotIsUsedByDialogAndSlotId=(slotId)=>{
    const { dispatch } = this.props;
    const {dialogId} = this.state;
    dispatch({
      type: 'dialogAdd/querySlotIsUsedByDialogAndSlotId',
      payload: {
        dialogId,
        slotId
      },
      callback:(res)=>{
        if(res.stageTitle.length>0){
          this.setState({
            slotDetailVisible:true,
            stageTitle:res.stageTitle
          })
        }else{
          this.addSlotToDialogByAdd(slotId,false)
        }
      }
    });
  };


  addSlot=()=>{
    this.fetchSlot();
    this.setState({
      visible:true
    })
  };

  handleCancel = () => {
    this.setState({ visible: false,slotDetailVisible:false });
  };

  searchSlot=(val)=>{
    this.setState({
      keys:val,
      slotLoading:true
    },()=>{
      this.fetchSlot();
    })
  };

  addSlotToDialog=(val)=>{
    let { slotList} = this.state;
    let isHased = false;
    slotList.map(i=>{
      isHased = i._id === val._id;
    });
    if(isHased){
      // let isHased = false;
       return message.error('该词槽已存在')
    }
    this.addSlotToDialogByAdd(val._id)
  };

  pageChange=(page)=>{
    this.setState({
      page,
      slotLoading:true
    },()=>{
      this.fetchSlot()
    })
  };

  limitChange=(limit)=>{
    this.setState({
      limit
    },()=>{
      this.fetchSlot()
    })
  }

  handleDelSlot=(slot)=>{
    this.querySlotIsUsedByDialogAndSlotId(slot._id);
  };

  forMap = tag => {
    const tagElem = (
      <Tag
        closable
        className={styles.slotItem}
        onClose={e => {
          e.preventDefault();
          this.handleDelSlot(tag);
        }}
      >
        {tag.name}-{tag.key}
      </Tag>
    );
    return (
      <span key={tag._id} style={{ display: 'inline-block' }}>
        {tagElem}
      </span>
    );
  };


  initDialog=(dialogId)=>{
    this.getStatusById();
    this.fetchDialogDetailByDialogId(dialogId);
    this.fetchDialogSlotByDialogId(dialogId);
  };


  getTrainResult =()=>{
    const { dispatch } = this.props;
    const {dialogId,dialogObj} = this.state;
    dispatch({
      type: 'dialogAdd/fetchTrainResult',
      payload: {
        dialogId
      },
      callback:(res)=>{
        console.log(res);
        let data ={
          x:[],
          y:[]
        };
        if(res.trainResults.length>0){
          for (let i = 0; i < res.trainResults.length; i += 1) {
            data.x.push(
             res.trainResults[i].stepIndex,
            );
            data.y.push(
              res.trainResults[i].loss
            );
          }
        }
        this.setState({
          dialogObj:res,
          data
        })
      }
    });
  };

  getProgress =()=>{
    const { dispatch } = this.props;
    const {dialogId,intervalId} = this.state;
    dispatch({
      type: 'dialogAdd/fetchProgress',
      payload: {
        dialogId
      },
      callback:(res)=>{
        console.log(res,'-------progress');
        console.log(res.status,'----------status');
        if(res.proportion!=undefined){
          this.setState({
            percent: Number.parseFloat(res.proportion).toFixed(2)
          });
        }
        if(res.proportion ===1){
          setTimeout(()=>{
            this.setState({
              training:false,
              percent:0
            })
          },1000);
          // message.info('训练完成');
          clearInterval(intervalId);
          return false;
        }
        if(res.status == 4 || res.status == 2){
          this.setState({
            percent:100
          });
          setTimeout(()=>{
            this.setState({
              training:false,
              percent:0
            })
          },1000);
          message.info('训练完成');
          clearInterval(intervalId);
          return false;
        }
      }
    });
  };

  getStatusById =(showMessage)=>{
    const { dispatch } = this.props;
    let {dialogId,training,status} = this.state;
    dispatch({
      type: 'dialogAdd/fetchStatusById',
      payload: {
        dialogId
      },
      callback:(res)=>{
        console.log(res.status,'----status');
        if(res.status ===2){
          // 训练已完成
          training =false;
          this.getTrainResult();
        }else if(res.status === 1){
          // 训练中
          training =true;
          const intervalId = setInterval(this.getProgress, 500);
          this.setState({intervalId});
        }else if(res.status === 0){
          // 未训练
         if(showMessage){
           message.info('改多轮会话尚未开始训练，暂时没有报表')
         }
        }else{
          // 已发布
          this.getTrainResult();
        }
        this.setState({
          training,
          status:res.status
        })
      }
    });
  };

  fetchDialogDetailByDialogId = (dialogId) =>{
    const { dispatch } = this.props;
    let {dialogData} = this.state;
    dispatch({
      type: 'dialogAdd/getDialog',
      payload: {
        dialogId
      },
      callback:(res)=>{
        console.log(res,'查询多轮数据结果');
        dialogData=res.dialogTemplate;
        this.setState({
          dialogData
        })
      }
    });
  };

  fetchDialogSlotByDialogId = (dialogId)=>{
    const { dispatch } = this.props;
    dispatch({
      type: 'dialogAdd/getDialogSlotsBydialogId',
      payload: {
        dialogId
      },
      callback:(res)=>{
        this.setState({
          slotList: res,
          slotLoading:false
        })
      }
    });
  };

  closeChart = e => {
    this.setState({
      chartsIsShow: false,
    });
  };

  showTrainRes=()=>{
    this.setState({
      chartsIsShow: true
    },()=>{
      this.getStatusById(true);
      this.getTrainResult();
    });
  };

  showTrainPro=()=>{
    this.setState({
      training : true
    },()=>{
     this.getProgress()
      const intervalId = setInterval(this.getProgress, 500);
      this.setState({intervalId});
    });
  };

  initEcharts=(obj)=>{
    myChart = echarts.init(document.getElementById(obj.id));
    this.chartsSetOpt(this.state.data)
  };

  chartsSetOpt=(data)=>{
    myChart.setOption({
      title: { text: ''},
      toolbox: {
        show : false,
      },
      tooltip: {
        trigger: 'axis'
      },
      xAxis : [
        {
          type : 'category',
          data : data.x,
          name:"训练次数"
        }
      ],
      yAxis : [
        {
          type : 'value',
          name:"误差值"
        }
      ],
      series : [
        {
          name: '',
          type: 'line',
          data: data.y,
          smooth: true
        }
      ]
    });
  };

  modalRef= (obj) => {
    if (obj && this.state.dialogObj !== null) {
      this.initEcharts(obj);
    }
  };

  checkName=(e)=>{
    const { dispatch } = this.props;
    const {dialogId,name } = this.state;
    const  dialogName = e.target.value;
    if(name === dialogName){
      return false
    }
    dispatch({
      type: 'dialogAdd/updateDialogNameById',
      payload: {
        dialogId,
        dialogName
      },
      callback:(res)=>{
        if(!res.code){
          message.info(res.msg)
        }
      }
    });
  };

  render() {
    const { getFieldDecorator } = this.props.form;
    const {visible,slotLoading,slotData,slotTotal,slotList,name,slotDetailVisible,stageTitle,dialogId,dialogData,training,chartsIsShow,percent,dialogObj} = this.state;
    const tagChild = slotList.map(this.forMap);

    return (
      <GridContent>
        <Suspense fallback={<PageLoading />}>
            <Row className={styles.colorBackground}>
              <Col style={{ padding: 10, }} xs={24}>
                <div className={styles.title}>
                  <span>会话编辑器</span>
                </div>
              </Col>
            </Row>
            <div style={{background:'#ffffff',marginBottom:10,padding:'10px 20px 5px'}}>
              <Form.Item {...formItemLayout} label="名称">
                {getFieldDecorator('name', {
                  rules: [
                    {
                      required: true,
                      message: '请输入多轮对话名称',
                    },
                  ],
                  initialValue: name
                })(<Input placeholder="请输入多轮对话名称" style={{marginLeft:10,width:200}} onBlur={e=>this.checkName(e)} />)}
              </Form.Item>
              <Form.Item {...formItemLayout} label="词槽">

                <div style={{marginLeft:10,display:'inline-block',width:'100%'}}>
                  <Spin spinning={slotLoading} delay={500}>
                    {tagChild}
                    <Button htmlType='button' type="primary" size='small' onClick={()=>this.addSlot()} className={styles.addSlotBtn}>添加词槽</Button>
                  </Spin>
                </div>
              </Form.Item>
            </div>
            <FlowPage dialogId={dialogId} data={dialogData} showCharts={this.showTrainRes} showTrains={this.showTrainPro} />
            <SlotModal
              total={slotTotal}
              visible={visible}
              listData={slotData}
              loading={slotLoading}
              alreadyExisted ={slotList}
              onCancel={this.handleCancel}
              searchSlot={this.searchSlot}
              pageChange={this.pageChange}
              addSlot={this.addSlotToDialog}
              limitChange={this.limitChange}
            />
            <Modal
              title="词槽使用详情"
              visible={slotDetailVisible}
              onOk={this.handleCancel}
              onCancel={this.handleCancel}
            >
              <p style={{textAlign:'center'}}> 该词槽正在被以下模块使用，不可删除</p>
              {
                stageTitle.map((item,index)=>{
                  return(
                    <p key={index} style={{color:'lightblue',textAlign:'center'}}>{item}</p>
                  )
                })
              }
            </Modal>
            <Modal
              title=""
              centered
              footer={null}
              closable={false}
              visible={training}
            >
              <p style={{textAlign:'center'}}>多轮对话训练中...</p>
               <div style={{textAlign:'center'}}>
                 <Progress type="circle" percent={percent*100} style={{margin:"0 auto"}} width={80} />
               </div>
            </Modal>
            {
              dialogObj!== null
              ?
                <Modal
                  title=""
                  centered
                  footer={null}
                  visible={chartsIsShow}
                  onCancel={this.closeChart}
                  width={773}
                >
                  <div className={styles.trainResBox}>
                    <div className={styles.head}>
                      <div className={styles.title}>
                        <img src={img1} alt="" style={{height: 30,marginLeft: 10,marginTop: 8}} />
                        <h3 style={{color:"#445474",textAlign:"center",marginTop:10,marginLeft:10}}>训练完成</h3>
                      </div>
                    </div>
                    <div className={styles.body}>
                      <Row>
                        <h3>训练结果</h3>
                      </Row>
                      <Row>
                        <h4 className={styles.time}>训练时间{dialogObj.fromFormat} 至 {dialogObj.toFormat}</h4>
                      </Row>
                      <Row>
                        <Col span={8}>
                          <ChartCard
                            title="训练时长"
                            avatar={
                              <img
                                alt="indicator"
                                style={{ width: 56, height: 56 }}
                                src={img2}
                              />
                            }
                            total={() => <span style={{fontSize:25}} dangerouslySetInnerHTML={{ __html: dialogObj.allTime+'秒'}} />}
                            footer={null}
                            contentHeight={46}
                          >
                          </ChartCard>
                        </Col>
                        <Col span={8}>
                          <ChartCard
                            title="迭代"
                            total={() => <span style={{fontSize:25}} dangerouslySetInnerHTML={{ __html: dialogObj.epochIndex+'次' }} />}
                            footer={null}
                            avatar={
                              <img
                                alt="indicator"
                                style={{ width: 56, height: 56 }}
                                src={img3}
                              />
                            }
                            contentHeight={46}
                          >
                          </ChartCard>
                        </Col>
                        <Col span={8}>
                          <ChartCard
                            title="准确率"
                            total={() => <span style={{fontSize:25}} dangerouslySetInnerHTML={{ __html:  (dialogObj.acc*100).toFixed(2)+'%'}} />}
                            footer={null}
                            avatar={
                              <img
                                alt="indicator"
                                style={{ width: 56, height: 56 }}
                                src={img4}
                              />
                            }
                            contentHeight={46}
                          >
                          </ChartCard>
                        </Col>
                      </Row>
                      <Row style={{marginTop:20}}>
                        <h3>误差曲线</h3>
                      </Row>
                      <div className={styles.charts}>
                        <div id="main" style={{ width: '100%', height: 350 }} ref={this.modalRef}></div>
                      </div>
                    </div>
                  </div>
                </Modal>
                :''
            }
        </Suspense>
      </GridContent>
    );
  }
}

export default connect (({ user }) => ({
  currentUser: user.currentUser
}))(Form.create()(DialogAdd));
